/******************************************************************************
* Student Name: Ofri Keidar
* Exercise Name: Ex2
* File Description: Class Edge's implementation. The class represents an edge in
* 				     a graph. Edge object links between two Nodes and can be
* 				     printed using a printing operator
******************************************************************************/

#include "Edge.h"

/***************************************************************************************
* function name: Edge(const Node nodeOut, const Node nodeIn)
* The Input: Two nodes to be linked by new edge
* The output: None
* The Function operation: Sets out-node and in-node pointers according to given origin
* 						  and destination, respectively. Given nodes are copied
***************************************************************************************/
Edge::Edge(const Node nodeOut, const Node nodeIn): m_out(*(new Node(nodeOut))), m_in(*(new Node(nodeIn))) {

	// TODO DEBUG PRINT!!!
	cout << "in edge constructor" << endl;

//	m_out = nodeOut; // set out-node reference to given origin
//	m_in = nodeIn; // set in-node reference to given destination
}

/***************************************************************************************
* function name: Edge(const Edge& edgeToCopy)
* The Input: Edge to be copied
* The output: None
* The Function operation: Sets out-node and in-node pointers according to given edge's
* 					      origin and destination, respectively. Given edge's nodes are copied
***************************************************************************************/
Edge::Edge(const Edge& edgeToCopy): m_out(*(new Node(edgeToCopy.m_out))), m_in(*(new Node(edgeToCopy.m_in))) {
	// TODO DEBUG PRINT!!!
	cout << "in edge COPY constructor" << endl;
}

/***************************************************************************************
* function name: ~Edge()
* The Input: None
* The output: None
* The Function operation: Deletes pointed nodes
***************************************************************************************/
Edge::~Edge() {
	// TODO DEBUG PRINT!!!
	cout << "in edge destructor" << endl;

	// delete pointed nodes
	delete &m_out;
	delete &m_in;
}

/***************************************************************************************
 * function name: == (const Edge& operand) const
 * The Input: Edge operand to compare with
 * The output: True if given operand is equal to object
 * The Function operation: Uses Node object's comparison operator and compares both edges'
 * 						   node attributes
 ***************************************************************************************/
bool Edge::operator == (const Edge& operand) const {
	return (m_out == operand.m_out) && (m_in == operand.m_in);
}

/***************************************************************************************
 * function name: < (const Edge& operand) const
 * The Input: Edge operand to compare with
 * The output: True if given operand's out and in nodes' values are bigger than object's
 * The Function operation: Uses Node object's comparison operator and compares both edges'
 * 						   node attributes
 ***************************************************************************************/
bool Edge::operator < (const Edge& operand) const {
	return (m_out < operand.m_out) && (m_in < operand.m_in);
}

/***************************************************************************************
 * function name: <= (const Edge& operand) const
 * The Input: Edge operand to compare with
 * The output: True if both edges' out node value is equal and  given operand's in node
 * 			   value is bigger
 * The Function operation: Uses Node object's comparison operator and compares both edges'
 * 						   node attributes
 ***************************************************************************************/
bool Edge::operator <= (const Edge& operand) const {
	return (m_out == operand.m_out) && (m_in < operand.m_in);
}

/***************************************************************************************
* function name: << (ostream &os, const Edge& edgeToPrint)
* The Input: Reference to Edge to be printed
* The output: ostream reference
* The Function operation: TODO
***************************************************************************************/
ostream& operator << (ostream &os, const Edge& edgeToPrint) {
	//return os << "[" << edgeToPrint.m_out.getNumber() << "->" << edgeToPrint.m_in.getNumber() << "]";
	return os << "[" << int(edgeToPrint.m_out) << "->" << int(edgeToPrint.m_in) << "]";
}
